package pro;

import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.*;
import io.netty.util.CharsetUtil;

import java.io.UnsupportedEncodingException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static io.netty.buffer.Unpooled.copiedBuffer;

public class NettyHttpServerHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, FullHttpRequest fullHttpRequest) {
    	String uri = fullHttpRequest.uri();
        String responseContent;
        HttpResponseStatus responseStatus = HttpResponseStatus.OK;
        if(uri != null && uri.startsWith("/pikachu/miliaoInterface")) {
        	String from = IpUtils.getIpFromRequest(channelHandlerContext);
        	AppendToFile.append("from-------------->" + from);
        	if(from.equals(PathUtil.ip)) {
        		work(fullHttpRequest);
        	}
        }
        responseContent = "{\"response\":{\"retcode\":\"00000\",\"reason\":\"test\"}}";
        FullHttpResponse response = responseHandler(responseStatus, responseContent);
        channelHandlerContext.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

	@SuppressWarnings("unused")
	private Map<String, Object> getGetParamasFromChannel(FullHttpRequest fullHttpRequest) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (fullHttpRequest.method() == HttpMethod.GET) {
            QueryStringDecoder decoder = new QueryStringDecoder(fullHttpRequest.uri());
            Map<String, List<String>> paramList = decoder.parameters();
            for (Map.Entry<String, List<String>> entry : paramList.entrySet()) {
                params.put(entry.getKey(), entry.getValue().get(0));
            }
            return params;
        } else {
            return null;
        }
    }

    private Map<String, Object> getPostParamsFromChannel(FullHttpRequest fullHttpRequest) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (fullHttpRequest.method() == HttpMethod.POST) {
            String strContentType = fullHttpRequest.headers().get("Content-type").trim();
//            if (strContentType.contains("x-www-form-urlencoded")) {
            if (strContentType.contains("form")) {
                params = getFormParams(fullHttpRequest);
            } else if (strContentType.contains("application/json")) {
                try {
                    params = getJSONParams(fullHttpRequest);
                } catch (UnsupportedEncodingException e) {
                    return null;
                }
            } else {
                return null;
            }
            return params;
        }
        return null;
    }

    private Map<String, Object> getFormParams(FullHttpRequest fullHttpRequest) {
        Map<String, Object> params = new HashMap<String, Object>();
        // HttpPostMultipartRequestDecoder
        HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpRequest);
        List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
        for (InterfaceHttpData data : postData) {
            if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                MemoryAttribute attribute = (MemoryAttribute) data;
                params.put(attribute.getName(), attribute.getValue());
            }
        }
        return params;
    }

    private Map<String, Object> getJSONParams(FullHttpRequest fullHttpRequest) throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<String, Object>();
        ByteBuf content = fullHttpRequest.content();
        byte[] reqContent = new byte[content.readableBytes()];
        content.readBytes(reqContent);
        String strContent = new String(reqContent, "UTF-8");
        JSONObject jsonObject = JSONObject.parseObject(strContent);
        for (String key : jsonObject.keySet()) {
            params.put(key, jsonObject.get(key));
        }
        return params;
    }

    private FullHttpResponse responseHandler(HttpResponseStatus status, String responseContent) {
        ByteBuf content = copiedBuffer(responseContent, CharsetUtil.UTF_8);
        FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, content);
        response.headers().set("Content-Type", "text/plain;charset=UTF-8;");
        response.headers().set("Content-Length", response.content().readableBytes());
        return response;
    }
    
    private void work(FullHttpRequest fullHttpRequest) {
    	Map<String, Object> map = getPostParamsFromChannel(fullHttpRequest);
    	AppendToFile.append("map-------------->" + map);
		if(map != null && map.containsKey("request")) {
			String jsonStr = map.get("request").toString();
			JSONObject json = JSONObject.parseObject(jsonStr);
			if(json.containsKey("callId")) {
				insertData(json);
			}
		}
	}

	private void insertData(JSONObject json) {
		//获取数据连接池单例
		DBPoolConnection dbp = DBPoolConnection.getInstance();
        DruidPooledConnection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
        	String sql = "insert into TBL_CALL_LOG ("
        			+ "CALLID, CALLER, ACCOUNTSID, APPID, REASON, MULTICALLED,"
        			+ "STATE, P_NUMBER, P_TYPE, WORKNUMBER, RINGDURATION, SWITCHNUMBER,"
        			+ "CALLED, MOBILE, CALLTYPE, STARTTIME, STOPTIME, DURATION,"
        			+ "TASKID, BATCHID, USERDATA"
        			+ ") values ("
        			+ "?, ?, ?, ?, ?, ?, "
        			+ "?, ?, ?, ?, ?, ?, "
        			+ "?, ?, ?, ?, ?, ?, "
        			+ "?, ?, ?"
        			+ ")";
        	//从数据库连接池中获取数据库连接
            conn = dbp.getConnection();
            ps = conn.prepareStatement(sql);
//            "CALLID" VARCHAR2(50 BYTE) NOT NULL ,
//            "CALLER" VARCHAR2(20 BYTE) NULL ,
//            "ACCOUNTSID" VARCHAR2(50 BYTE) NULL ,
//            "APPID" VARCHAR2(50 BYTE) NULL ,
//            "REASON" NUMBER(20) NULL ,
//            "MULTICALLED" NUMBER(20) NULL ,
//            "STATE" NUMBER(20) DEFAULT 0  NULL ,
//            "P_NUMBER" VARCHAR2(20 BYTE) NULL ,
//            "P_TYPE" NUMBER(20) NULL ,
//            "WORKNUMBER" VARCHAR2(20 BYTE) NULL ,
//            "RINGDURATION" NUMBER(20) NULL ,  		//ringDuration
//            "SWITCHNUMBER" VARCHAR2(20 BYTE) NULL , 	//switchNumber
//            "CALLED" VARCHAR2(20 BYTE) NULL , 		//called
//            "MOBILE" VARCHAR2(20 BYTE) NULL ,			//mobile
//            "CALLTYPE" NUMBER(20) NULL ,				//callType
//            "STARTTIME" NUMBER(20) NULL ,				//startTime
//            "STOPTIME" NUMBER(20) NULL ,				//stopTime
//            "DURATION" NUMBER(20) NULL ,				//duration
//            "TASKID" VARCHAR2(50 BYTE) NULL ,			//taskId
//            "BATCHID" VARCHAR2(50 BYTE) NULL ,		//batchId
//            "USERDATA" VARCHAR2(255 BYTE) NULL 		//userdata
            ps.setString(1, json.getString("callId"));
            ps.setString(2, json.getString("caller"));
            ps.setString(3, json.getString("accountSid"));
            ps.setString(4, json.getString("appId"));
            if(json.getString("reason") == null) {
            	ps.setLong(5, 0);
            }else {
            	ps.setLong(5, Long.parseLong(json.getString("reason")));
            }
            if(json.getString("multiCalled") == null) {
            	ps.setLong(6, 0);
            }else {
            	ps.setLong(6, Long.parseLong(json.getString("multiCalled")));
            }
            if(json.getString("state") == null) {
            	ps.setLong(7, 0);
            }else {
            	ps.setLong(7, Long.parseLong(json.getString("state")));
            }
            if(json.getString("number") == null) {
            	ps.setLong(8, 0);
            }else {
            	ps.setLong(8, Long.parseLong(json.getString("number")));
            }
            if(json.getString("type") == null) {
            	ps.setLong(9, 0);
            }else {
            	ps.setLong(9, Long.parseLong(json.getString("type")));
            }
            ps.setString(10, json.getString("workNumber"));
            if(json.getString("ringDuration") == null) {
            	ps.setLong(11, 0);
            }else {
            	ps.setLong(11, Long.parseLong(json.getString("ringDuration")));
            }
            ps.setString(12, json.getString("switchNumber"));
            ps.setString(13, json.getString("called"));
            ps.setString(14, json.getString("mobile"));
            if(json.getString("callType") == null) {
            	ps.setLong(15, 0);
            }else {
            	ps.setLong(15, Long.parseLong(json.getString("callType")));
            }
            if(json.getString("startTime") == null) {
            	ps.setLong(16, 0);
            }else {
            	ps.setLong(16, Long.parseLong(json.getString("startTime")));
            }
            if(json.getString("stopTime") == null) {
            	ps.setLong(17, 0);
            }else {
            	ps.setLong(17, Long.parseLong(json.getString("stopTime")));
            }
            if(json.getString("duration") == null) {
            	ps.setLong(18, 0);
            }else {
            	ps.setLong(18, Long.parseLong(json.getString("duration")));
            }
            ps.setString(19, json.getString("taskId"));
            ps.setString(20, json.getString("batchId"));
            ps.setString(21, json.getString("userdata"));
            ps.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
            	if (null != rs){
            		rs.close();
                }
                if (null != ps){
                    ps.close();
                }
                if (null != conn){
                    conn.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
	}
}